package com.zxmr.domain.service;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.zxmr.CommonInit;
import com.zxmr.db.DBManager;
import com.zxmr.domain.account.User;
import com.zxmr.domain.file.DeleteFile;
import com.zxmr.domain.file.File;
import com.zxmr.domain.file.Folder;
import com.zxmr.domain.file.ResourceAction;
import com.zxmr.domain.file.ResourceAuthorization;
import com.zxmr.domain.file.ResourceLevel;
import com.zxmr.domain.file.ResourceType;
import com.zxmr.domain.file.SystemFolder;
import com.zxmr.domain.file.SystemFolderType;

public class ResourceService {

	DBManager db = CommonInit.getDBManager();
	
	public long addFile(File file)
	{
		try
		{
			return (Long)db.getMapper().insert("resource.addFile", file);
		}catch(SQLException e)
		{
			e.printStackTrace();
		}
		return -1;
	}
	public boolean updateFile(File file)
	{
		try
		{
			db.getMapper().update("resource.updateFile", file);
			return true;
		}catch(SQLException e)
		{
			e.printStackTrace();
		}
		return false;
	}
	/**
	 * update folder parameter, if level changed then need to consider if need to reset level of sub folders
	 * @param folder
	 * @param orignLevel
	 * @return
	 */
	public boolean updateFolder(Folder folder,ResourceLevel orignLevel)
	{
		try
		{
			db.getMapper().startTransaction();
			db.getMapper().update("resource.updateFolder", folder);
			
			//if orign is protected then need to delete all authorization
			if(orignLevel == ResourceLevel.Protected && folder.getLevel()!= orignLevel)
			{
				db.getMapper().delete("resource.deleteFolderAuth", folder);
			}
			// 如果权限变小则需要改变子目录的权限
			if(folder.getLevel().getIndex() < orignLevel.getIndex())
			{
				// there is only public protected private, so if level down then there need to reset authorization table
				this.copyParentLevel(folder,orignLevel,true);
			}
			db.getMapper().commitTransaction();
			return true;
		}catch(SQLException e)
		{
			e.printStackTrace();
		}finally{
			try {
				db.getMapper().endTransaction();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return false;
	}
	private void doDeleteFile(File file) throws SQLException
	{
		db.getMapper().delete("resource.deleteFile",file);
		DeleteFile delete = new DeleteFile();
		delete.setUrl(file.getUrl());
		this.addDeleteFile(delete);
	}
	public boolean deleteFile(File file)
	{
		try
		{
			db.getMapper().startTransaction();
			doDeleteFile(file);
			
			db.getMapper().commitTransaction();
			return true;
		}catch(SQLException e)
		{
			e.printStackTrace();
		}
		finally
		{
			try {
				db.getMapper().endTransaction();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return false;
	}
	public long addFolder(Folder folder)
	{
		try
		{
			return (Long)db.getMapper().insert("resource.addFolder", folder);
		}catch(SQLException e)
		{
			e.printStackTrace();
		}
		return -1;
	}
	public boolean deleteFolder(Folder folder)
	{
		try {
			db.getMapper().startTransaction();
			doDeleteFolder(folder);
			db.getMapper().commitTransaction();
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		}finally
		{
			try {
				db.getMapper().endTransaction();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return false;
	}
	@SuppressWarnings("unchecked")
	private void doDeleteFolder(Folder folder) throws SQLException
	{
		
		List<Folder> subFolders = db.getMapper().queryForList("resource.findFolderIDByParent", folder);
		List<File> subFiles = db.getMapper().queryForList("resource.findFileWithURLByFolder", folder);
		
		db.getMapper().delete("resource.deleteFolder", folder);
		
		
		db.getMapper().delete("resource.deleteFolderAuth", folder);
		if(subFiles!=null && !subFiles.isEmpty())
		{
			db.getMapper().delete("resource.deleteFileByFolder", folder);
			for(File file : subFiles)
			{
				doDeleteFile(file);
			}
		}
		if(subFolders != null && !subFolders.isEmpty())
		{
			db.getMapper().delete("resource.deleteFolderByFolder", folder);
			for(Folder sub : subFolders)
			{
				doDeleteFolder(sub);
			}
		}
		
	}
	@SuppressWarnings("unchecked")
	public List<File> queryAllFile(long folder,int company)
	{
		Map<String,Object> para = new HashMap<String,Object>();
		para.put("id", folder);
		para.put("company", company);
		
		try
		{
			return (List<File>)db.getMapper().queryForList("resource.findAllFileByFolder", para);
		}catch(SQLException e)
		{
			e.printStackTrace();
		}
		return null;
	}
	@SuppressWarnings("unchecked")
	public List<Folder> queryAllFolder(long folder,int company)
	{
		Map<String,Object> para = new HashMap<String,Object>();
		para.put("id", folder);
		para.put("company", company);
		
		try
		{
			return (List<Folder>)db.getMapper().queryForList("resource.findAllFolderByFolder", para);
		}catch(SQLException e)
		{
			e.printStackTrace();
		}
		return null;
	}
	
	public File queryFile(long id,int company)
	{
		Map<String,Object> para = new HashMap<String,Object>();
		para.put("id", id);
		para.put("company", company);
		try
		{
			return (File)db.getMapper().queryForObject("resource.findFileByID", para);
		}catch(SQLException e)
		{
			e.printStackTrace();
		}
		return null;
	}
	
	public Folder queryFolder(long id,int company)
	{
		Map<String,Object> para = new HashMap<String,Object>();
		para.put("id", id);
		para.put("company", company);
		try
		{
			return (Folder)db.getMapper().queryForObject("resource.findFolderByID", para);
		}catch(SQLException e)
		{
			e.printStackTrace();
		}
		return null;
	}
	public boolean addResourceAuth(ResourceAuthorization ra)
	{
		try
		{
			db.getMapper().insert("resource.addResourceAuth",ra);
			return true;
		}catch(SQLException e)
		{
			e.printStackTrace();
		}
		return false;
	}
	public boolean deleteResourceAuth(ResourceAuthorization ra)
	{
		
		try
		{
			db.getMapper().startTransaction();
			db.getMapper().delete("resource.deleteResourceAuth", ra);
			deleteSubFolderResourceAuth(ra);
			db.getMapper().commitTransaction();
			return true;
		}catch(SQLException e)
		{
			e.printStackTrace();
		}finally{
			try {
				db.getMapper().endTransaction();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return false;
	}
	
	private void deleteSubFolderResourceAuth(ResourceAuthorization ra) throws SQLException
	{
		Map<String,Object> para = new HashMap<String,Object>();
		para.put("id", ra.getResourceId());
		para.put("company", ra.getCompany());
		
		@SuppressWarnings("unchecked")
		List<Folder> childs = db.getMapper().queryForList("resource.findAllFolderByFolder", para);
		
		if(childs == null || childs.isEmpty())
			return;
		
		for(Folder f : childs)
		{
			ra.setResourceId(f.getId());
			db.getMapper().delete("resource.deleteResourceAuth", ra);
			deleteSubFolderResourceAuth(ra);
		}
	}
	@SuppressWarnings("unchecked")
	public List<ResourceAuthorization> queryAuthForFolder(ResourceQueryBean bean)
	{
		try
		{
			return (List<ResourceAuthorization>)db.getMapper().queryForList("resource.queryAuthForFolder", bean);
		}catch(SQLException e)
		{
			e.printStackTrace();
		}
		return null;
	}
	
	public boolean authFolder(long folder,int company)
	{
		try
		{
			Map<String,Object> para = new HashMap<String,Object>();
			para.put("id", folder);
			para.put("company", company);
			
			int num = (Integer)db.getMapper().queryForObject("resource.authFolder", para);
			if(num == 1)return true;
		}catch(SQLException e)
		{
			e.printStackTrace();
		}
		return false;
	}
	
	public void copyParentFolderAuth(long parent,long child,int company)
	{
		try
		{
			ResourceQueryBean bean = new ResourceQueryBean();
			bean.setCompany(company);
			bean.setResourceId(parent);
			@SuppressWarnings("unchecked")
			List<ResourceAuthorization> parentAuth = (List<ResourceAuthorization>)
							db.getMapper().queryForList("resource.queryAuthForFolderDetail", bean);
			if(parentAuth == null || parentAuth.isEmpty())
				return;
			
			for(ResourceAuthorization ra : parentAuth)
			{
				ra.setResourceId(child);
				this.addResourceAuth(ra);
			}
			
		}catch(SQLException e)
		{
			e.printStackTrace();
		}

	}

	private void copyParentLevel(Folder parent,ResourceLevel orign,boolean resetAuth) throws SQLException
	{
		Map<String,Object> para = new HashMap<String,Object>();
		para.put("id", parent.getId());
		para.put("company", parent.getCompany());
		
		@SuppressWarnings("unchecked")
		List<Folder> childs = db.getMapper().queryForList("resource.findAllFolderByFolder", para);
		if(childs == null || childs.isEmpty())
			return;
		
		for(Folder f : childs)
		{
			f.setCompany(parent.getCompany());
			if(resetAuth)
				db.getMapper().delete("resource.deleteFolderAuth",f);
			
			ResourceLevel l = f.getLevel();
			
			// update folder level
			if(f.getLevel().getIndex() > parent.getLevel().getIndex())
			{
				f.setLevel(parent.getLevel());
				f.setCompany(parent.getCompany());
				
				db.getMapper().update("resource.updateFolderLevel", f);
			}
			
			copyParentLevel(f,l,resetAuth);
		}
	}
	public boolean isUserAuthorizedForAction(long folder,User user,ResourceAction action)
	{

		ResourceQueryBean queryBean = new ResourceQueryBean();
		queryBean.setAction(action);
		queryBean.setCompany(user.getCompany());
		queryBean.setResourceId(folder);
		queryBean.setResourceType(ResourceType.Folder);
		queryBean.setUser(user.getId());
		
		try
		{
			int num = (Integer)db.getMapper().queryForObject("resource.queryAuthForUserAction", queryBean);
			if(num > 0)return true;
		}catch(SQLException e)
		{
			e.printStackTrace();
		}
		return false;
	}
	
	public void addDeleteFile(DeleteFile file)
	{
		try
		{
			db.getMapper().insert("resource.insertDeleteFile", file);
		}catch(SQLException e)
		{
			e.printStackTrace();
		}
	}
	@SuppressWarnings("unchecked")
	public List<DeleteFile> queryDeleteFile()
	{
		try
		{
			return (List<DeleteFile>)db.getMapper().queryForList("resource.queryAllDeleteFile");
		}catch(SQLException e)
		{
			e.printStackTrace();
		}
		return null;
	}
	public void deleteDeleteFile(DeleteFile file)
	{
		try
		{
			db.getMapper().delete("resource.deleteDeleteFile",file.getId());
		}catch(SQLException e)
		{
			e.printStackTrace();
		}
	}
	
	@SuppressWarnings("unchecked")
	public SystemFolder querySystemFolder(int company,String type)
	{
		try
		{
			SystemFolder para = new SystemFolder();
			para.setCompany(company);
			para.setType(type);
			List<SystemFolder> result = (List<SystemFolder>)db.getMapper().queryForList("resource.querySystemFolder", para);
			if(result == null || result.isEmpty())
				return null;
			
			return result.get(0);
		}catch(SQLException e)
		{
			e.printStackTrace();
		}
		return null;
	}
	@SuppressWarnings("unchecked")
	public List<SystemFolderType> queryAllSystemFolderType()
	{
		try
		{
			List<SystemFolderType> result = (List<SystemFolderType>)db.getMapper().queryForList("resource.queryAllSystemFolderType");
			
			return result;
		}catch(SQLException e)
		{
			e.printStackTrace();
		}
		return null;
	}
}
